package com.gitee.wsl.common.ui.theme

import com.gitee.wsl.common.ui.theme.local.DarkTheme
import com.gitee.wsl.common.ui.theme.local.LightTheme
import com.gitee.wsl.common.ui.theme.local.Material3ColorPalette
import com.gitee.wsl.data.store.StoreControl
import com.gitee.wsl.data.store.StoreServer
import com.gitee.wsl.data.store.getPreferenceOrNull
import kotlinx.serialization.Serializable
import kotlin.properties.ReadOnlyProperty
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

interface ColorPaletteBean {

    /**
     * 玫瑰红色
     */
    var rosewater: Long

    /**
     * 火红色
     */

    var flamingo: Long

    /**
     * 粉红色
     */
    var pink: Long

    /**
     * 淡紫色
     */
    var mauve: Long

    var red: Long

    /**
     * 褐红色
     */
    var maroon: Long


    /**
     * 桃红色
     */
    var peach: Long

    var yellow: Long

    var green: Long

    /**
     * 青绿
     */
    var teal: Long

    var sky: Long

    /**
     * 天蓝色
     */
    var sapphire: Long

    var blue: Long

    /**
     * 淡紫色
     */
    var lavender: Long

    /**
     * Typography
     *
     * Subtle
     *   Comments, Footnotes, Inactive Text
     *      Overlay 1
     *
     * Highlights
     *   Links, URLs  -> Rosewater
     *   Success      -> Green
     *   Warnings     -> Peach
     *   Errors       -> Maroon
     *   Search Results, Tags -> Blue
     */

    //Foreground	Main Text, Body Copy
    //  Text
    var text: Long

    //Subtext	Secondary Text, Headlines, Labels
    //  Subtext 0, Subtext 1
    var subtext0: Long

    var subtext1: Long


    //Overlays	Splits, Floating Elements
    //  Overlay 0,Overlay 1,Overlay 2
    var overlay0: Long

    var overlay1: Long

    var overlay2: Long


    //Surface Elements	Sign Columns, Cursor Line, Generic Buttons, Inputs
    //  Surface 0,Surface 1,Surface 2

    var surface0: Long

    var surface1: Long

    var surface2: Long


    //Background Pane	Main Canvas, Page Background Base
    var base: Long

    //Secondary Panes	Secondary Canvases, Content Boxes, Sidebars
    // Crust,Mantle
    var mantle: Long

    var crust: Long
}


interface ColorPaletteScheme: ColorPaletteBean {

    /**
     * Syntax Colours
     */
    val textDisabled : Long
        get() = teal

    val mark1 : Long
        get() = lavender
    val mark1Text:Long
        get() = crust

    val mark2 : Long
        get() = mauve
    val mark2Text : Long
        get() = sky

    val mark3 : Long
        get() = sapphire
    val mark3Text : Long
        get() = rosewater


    /**
     * Window Colours
     */
    val background : Long
        get() = base

    val mainText : Long
        get() = text

    val urls : Long
        get() = rosewater

    val selection : Long
        get() = lavender

    val selectionText : Long
        get() = subtext0

    val cursor : Long
        get() = rosewater

    val cursorText : Long
        get() = base

    val activeBorder : Long
        get() = lavender

    val inactiveBorder : Long
        get() = overlay0

    val bellBorder : Long
        get() = yellow

    /**
     * Regular Colours
     */
    val color0 : Long
        get() = surface1
    val color1 : Long
        get() = flamingo
    val color2 : Long
        get() = green
    val color3 : Long
        get() = yellow
    val color4 : Long
        get() = blue
    val color5 : Long
        get() = pink
    val color6 : Long
        get() = teal
    val color7 : Long
        get() = sapphire

    /**
     * Regular Relative Colours
     * 相对色,用于反差大的
     */
    val color0Relative : Long
        get() = subtext1
    val color1Relative : Long
        get() = teal
    val color2Relative : Long
        get() = yellow
    val color3Relative : Long
        get() = green
    val color4Relative : Long
        get() = pink
    val color5Relative : Long
        get() = blue
    val color6Relative : Long
        get() = flamingo
    val color7Relative : Long
        get() = surface1

    /**
     * Regular Accompany Colours
     * 相伴色,用于一同显示,看上去不突兀
     */
    val color0Accompany : Long
        get() = surface2
    val color1Accompany : Long
        get() = red
    val color2Accompany : Long
        get() = color2
    val color3Accompany : Long
        get() =  color3
    val color4Accompany : Long
        get() =  color4
    val color5Accompany : Long
        get() =  color5
    val color6Accompany : Long
        get() =  color6
    val color7Accompany : Long
        get() = color7

    /**
     * Regular Accompany other Colours
     * 第二种 相伴色
     */
    val color0Accompany1 : Long
        get() =  color0
    val color1Accompany1 : Long
        get() =  color1
    val color2Accompany1 : Long
        get() =  color2
    val color3Accompany1 : Long
        get() =  color3
    val color4Accompany1 : Long
        get() =  color4
    val color5Accompany1 : Long
        get() =  color5
    val color6Accompany1 : Long
        get() =  color6
    val color7Accompany1 : Long
        get() =  color7

    /**
     * Bold Colours
     */
    val boldColor0 : Long
        get() = rosewater
    val boldColor1 : Long
        get() = red
    val boldColor2 : Long
        get() = green
    val boldColor3 : Long
        get() = yellow
    val boldColor4 : Long
        get() = blue
    val boldColor5 : Long
        get() = pink
    val boldColor6 : Long
        get() = teal
    val boldColor7 : Long
        get() = lavender


    /**
     * Extended Colours
     */
    val color16 : Long
        get() = peach
    val color17 : Long
        get() = rosewater

    fun fromName(name: String):Long

    fun toCompose(): ComposeColorPaletteScheme<Long>

    fun toAndroid(): ComposeColorPaletteScheme<Int>

    fun getColorThemeName():String

}


const val ColorPalette_Frappe:String = "frappe"
const val ColorPalette_Mocha:String = "mocha"
const val ColorPalette_Latte:String = "latte"
const val ColorPalette_Macchiato:String = "macchiato"
const val ColorPalette_LIGHT:String = "light"
const val ColorPalette_DARK:String = "dark"
const val ColorPalette_SYSTEM:String = "system"


open class Light: ColorPaletteSchemeBase(defaultLightColorSet) {
    override fun getColorThemeName(): String {
       return  ColorPalette_LIGHT
    }

    override fun toCompose(): ComposeColorPaletteScheme<Long> {
        return Material3ColorPalette.LightTheme
    }
}

open class Dark: ColorPaletteSchemeBase(defaultDarkColorSet) {
    override fun getColorThemeName(): String {
        return ColorPalette_DARK
    }

    override fun toCompose(): ComposeColorPaletteScheme<Long> {
        return Material3ColorPalette.DarkTheme
    }
}

open class Frappe: ColorPaletteSchemeBase(frappe) {
    override fun getColorThemeName(): String {
        return ColorPalette_Frappe
    }
}

open class Mocha: ColorPaletteSchemeBase(mocha) {
    override fun getColorThemeName(): String {
        return ColorPalette_Mocha
    }
}

open class Macchiato: ColorPaletteSchemeBase(macchiato) {
    override fun getColorThemeName(): String {
        return ColorPalette_Macchiato
    }
}

open class Latte: ColorPaletteSchemeBase(latte){
    override val mark1Text: Long
        get() = base
    override val mark2Text: Long
        get() = base
    override val mark3Text: Long
        get() = base

    override val color0 : Long
        get() = subtext1

    override val color7 : Long
        get() = surface2

    override val boldColor0 : Long
        get() = subtext0

    override val boldColor7 : Long
        get() = surface1

    override fun getColorThemeName(): String {
        return ColorPalette_Latte
    }
}

//textColorPrimary                   :T  ">@color/m3_default_color_primary_text</item>
//textColorPrimaryInverse            :T  ">@color/m3_dark_default_color_primary_text</item>
//textColorSecondary                 :T  ">@color/m3_default_color_secondary_text</item>
//textColorSecondaryInverse          :T  ">@color/m3_dark_default_color_secondary_text</item>
//textColorTertiary                  :T  ">@color/m3_default_color_secondary_text</item>
//textColorTertiaryInverse           :T  ">@color/m3_dark_default_color_secondary_text</item>
//textColorPrimaryDisableOnly        :T  ">@color/m3_primary_text_disable_only</item>
//textColorPrimaryInverseDisableOnly :T  ">@color/m3_dark_primary_text_disable_only</item>
//textColorHint                      :T  ">@color/m3_hint_foreground</item>
//textColorHintInverse               :T  ">@color/m3_dark_hint_foreground</item>
//textColorHighlight                 :T  ">@color/m3_highlighted_text</item>
//textColorHighlightInverse          :T  ">@color/m3_dark_highlighted_text</item>
//textColorLink                      :T  ">?attr/colorPrimary</item>
//textColorLinkInverse               :T  ">?attr/colorPrimaryInverse</item>
//textColorAlertDialogListItem       :T  ">@color/m3_default_color_primary_text</item>

interface ComposeColorPaletteScheme<T>{
    var primary :T
    var onPrimary :T
    var primaryContainer :T
    var onPrimaryContainer :T
    var inversePrimary :T
    var secondary :T
    var onSecondary :T
    var secondaryContainer :T
    var onSecondaryContainer :T
    var tertiary :T
    var onTertiary :T
    var tertiaryContainer :T
    var onTertiaryContainer :T
    var error :T
    var onError :T
    var errorContainer :T
    var onErrorContainer :T
    var background :T
    var onBackground :T
    var surface :T
    var onSurface :T
    var inverseSurface :T
    var inverseOnSurface :T
    var surfaceVariant :T
    var onSurfaceVariant :T
    var outline :T
    var shadow :T
    var surfaceTint :T
    var outlineVariant :T
    var scrim :T

    var textColorPrimary                   :T
    var textColorPrimaryInverse            :T
    var textColorSecondary                 :T
    var textColorSecondaryInverse          :T
    var textColorTertiary                  :T
    var textColorTertiaryInverse           :T
    var textColorPrimaryDisableOnly        :T
    var textColorPrimaryInverseDisableOnly :T
    var textColorHint                      :T
    var textColorHintInverse               :T
    var textColorHighlight                 :T
    var textColorHighlightInverse          :T
    var textColorLink                      :T
    var textColorLinkInverse               :T
    var textColorAlertDialogListItem       :T

}


class ComposeColorPaletteSchemeSub(val baseColorPalette:()-> ColorPaletteScheme):
    ComposeColorPaletteScheme<Long> {
    override var primary :Long by SubColorPaletteProp{
        baseColorPalette().text
    }
    override var onPrimary :Long by SubColorPaletteProp{
        baseColorPalette().overlay0
    }
    override var primaryContainer :Long by SubColorPaletteProp{
        baseColorPalette().base
    }
    override var onPrimaryContainer :Long by SubColorPaletteProp{
        baseColorPalette().overlay1
    }
    override var inversePrimary :Long by SubColorPaletteProp{
        baseColorPalette().surface0
    }
    override var secondary :Long by SubColorPaletteProp{
        baseColorPalette().subtext0
    }
    override var onSecondary :Long by SubColorPaletteProp{
        baseColorPalette().surface1
    }
    override var secondaryContainer :Long by SubColorPaletteProp{
        baseColorPalette().surface2
    }
    override var onSecondaryContainer :Long by SubColorPaletteProp{
        baseColorPalette().overlay2
    }
    override var tertiary :Long by SubColorPaletteProp{
        baseColorPalette().subtext1
    }
    override var onTertiary :Long by SubColorPaletteProp{
        baseColorPalette().mauve
    }
    override var tertiaryContainer :Long by SubColorPaletteProp{
        baseColorPalette().surface1
    }
    override var onTertiaryContainer :Long by SubColorPaletteProp{
        baseColorPalette().overlay1
    }
    override var error :Long by SubColorPaletteProp{
        baseColorPalette().red
    }
    override var onError :Long by SubColorPaletteProp{
        baseColorPalette().sky
    }
    override var errorContainer :Long by SubColorPaletteProp{
        baseColorPalette().surface0
    }
    override var onErrorContainer :Long by SubColorPaletteProp{
        baseColorPalette().overlay0
    }
    override var background :Long by SubColorPaletteProp{
        baseColorPalette().base
    }
    override var onBackground :Long by SubColorPaletteProp{
        baseColorPalette().text
    }
    override var surface :Long by SubColorPaletteProp{
        baseColorPalette().surface0
    }
    override var onSurface :Long by SubColorPaletteProp{
        baseColorPalette().overlay0
    }
    override var inverseSurface :Long by SubColorPaletteProp{
        baseColorPalette().surface1
    }
    override var inverseOnSurface :Long by SubColorPaletteProp{
        baseColorPalette().overlay1
    }
    override var surfaceVariant :Long by SubColorPaletteProp{
        baseColorPalette().base
    }
    override var onSurfaceVariant :Long by SubColorPaletteProp{
        baseColorPalette().subtext1
    }
    override var outline :Long by SubColorPaletteProp{
        baseColorPalette().boldColor0
    }
    override var shadow: Long by SubColorPaletteProp{
        baseColorPalette().bellBorder
    }
    override var surfaceTint: Long by SubColorPaletteProp{
        baseColorPalette().surface0
    }
    override var outlineVariant: Long by SubColorPaletteProp{
        baseColorPalette().boldColor1
    }
    override var scrim: Long by SubColorPaletteProp{
        baseColorPalette().crust
    }

    override var textColorPrimary: Long by SubColorPaletteProp{
        baseColorPalette().text
    }
    override var textColorPrimaryInverse: Long by SubColorPaletteProp{
        baseColorPalette().selection
    }
    override var textColorSecondary: Long by SubColorPaletteProp{
        baseColorPalette().color3
    }
    override var textColorSecondaryInverse: Long by SubColorPaletteProp{
        baseColorPalette().color3Relative
    }
    override var textColorTertiary: Long by SubColorPaletteProp{
        baseColorPalette().color4
    }
    override var textColorTertiaryInverse: Long by SubColorPaletteProp{
        baseColorPalette().color4Relative
    }
    override var textColorPrimaryDisableOnly: Long by SubColorPaletteProp{
        baseColorPalette().color5
    }
    override var textColorPrimaryInverseDisableOnly: Long by SubColorPaletteProp{
        baseColorPalette().color5Relative
    }
    override var textColorHint: Long by SubColorPaletteProp{
        baseColorPalette().textDisabled
    }
    override var textColorHintInverse: Long by SubColorPaletteProp{
        baseColorPalette().text
    }
    override var textColorHighlight: Long by SubColorPaletteProp{
        baseColorPalette().color2
    }
    override var textColorHighlightInverse: Long by SubColorPaletteProp{
        baseColorPalette().color2Relative
    }
    override var textColorLink: Long by SubColorPaletteProp{
        baseColorPalette().urls
    }
    override var textColorLinkInverse: Long by SubColorPaletteProp{
        baseColorPalette().textDisabled
    }
    override var textColorAlertDialogListItem: Long by SubColorPaletteProp{
        baseColorPalette().text
    }
}

class AndroidColorPaletteSchemeSub(val composeColorPalette:()-> ComposeColorPaletteScheme<Long>):
    ComposeColorPaletteScheme<Int> {
    override var primary :Int by SubColorPaletteProp{
        composeColorPalette().primary.toInt()
    }
    override var onPrimary :Int by SubColorPaletteProp{
        composeColorPalette().onPrimary.toInt()
    }
    override var primaryContainer :Int by SubColorPaletteProp{
        composeColorPalette().primaryContainer.toInt()
    }
    override var onPrimaryContainer :Int by SubColorPaletteProp{
        composeColorPalette().onPrimaryContainer.toInt()
    }
    override var inversePrimary :Int by SubColorPaletteProp{
        composeColorPalette().inversePrimary.toInt()
    }
    override var secondary :Int by SubColorPaletteProp{
        composeColorPalette().secondary.toInt()
    }
    override var onSecondary :Int by SubColorPaletteProp{
        composeColorPalette().onSecondary.toInt()
    }
    override var secondaryContainer :Int by SubColorPaletteProp{
        composeColorPalette().secondaryContainer.toInt()
    }
    override var onSecondaryContainer :Int by SubColorPaletteProp{
        composeColorPalette().onSecondaryContainer.toInt()
    }
    override var tertiary :Int by SubColorPaletteProp{
        composeColorPalette().tertiary.toInt()
    }
    override var onTertiary :Int by SubColorPaletteProp{
        composeColorPalette().onTertiary.toInt()
    }
    override var tertiaryContainer :Int by SubColorPaletteProp{
        composeColorPalette().tertiaryContainer.toInt()
    }
    override var onTertiaryContainer :Int by SubColorPaletteProp{
        composeColorPalette().onTertiaryContainer.toInt()
    }
    override var error :Int by SubColorPaletteProp{
        composeColorPalette().error.toInt()
    }
    override var onError :Int by SubColorPaletteProp{
        composeColorPalette().onError.toInt()
    }
    override var errorContainer :Int by SubColorPaletteProp{
        composeColorPalette().errorContainer.toInt()
    }
    override var onErrorContainer :Int by SubColorPaletteProp{
        composeColorPalette().onErrorContainer.toInt()
    }
    override var background :Int by SubColorPaletteProp{
        composeColorPalette().background.toInt()
    }
    override var onBackground :Int by SubColorPaletteProp{
        composeColorPalette().onBackground.toInt()
    }
    override var surface :Int by SubColorPaletteProp{
        composeColorPalette().surface.toInt()
    }
    override var onSurface :Int by SubColorPaletteProp{
        composeColorPalette().onSurface.toInt()
    }
    override var inverseSurface :Int by SubColorPaletteProp{
        composeColorPalette().inverseSurface.toInt()
    }
    override var inverseOnSurface :Int by SubColorPaletteProp{
        composeColorPalette().inverseOnSurface.toInt()
    }
    override var surfaceVariant :Int by SubColorPaletteProp{
        composeColorPalette().surfaceVariant.toInt()
    }
    override var onSurfaceVariant :Int by SubColorPaletteProp{
        composeColorPalette().onSurfaceVariant.toInt()
    }
    override var outline :Int by SubColorPaletteProp{
        composeColorPalette().outline.toInt()
    }
    override var shadow: Int by SubColorPaletteProp{
        composeColorPalette().shadow.toInt()
    }
    override var surfaceTint: Int by SubColorPaletteProp{
        composeColorPalette().surfaceTint.toInt()
    }
    override var outlineVariant: Int by SubColorPaletteProp{
        composeColorPalette().outlineVariant.toInt()
    }
    override var scrim: Int by SubColorPaletteProp{
        composeColorPalette().scrim.toInt()
    }

    override var textColorPrimary: Int by SubColorPaletteProp{
        composeColorPalette().textColorPrimary.toInt()
    }
    override var textColorPrimaryInverse: Int by SubColorPaletteProp{
        composeColorPalette().textColorPrimaryInverse.toInt()
    }
    override var textColorSecondary: Int by SubColorPaletteProp{
        composeColorPalette().textColorSecondary.toInt()
    }
    override var textColorSecondaryInverse: Int by SubColorPaletteProp{
        composeColorPalette().textColorSecondaryInverse.toInt()
    }
    override var textColorTertiary: Int by SubColorPaletteProp{
        composeColorPalette().textColorTertiary.toInt()
    }
    override var textColorTertiaryInverse: Int by SubColorPaletteProp{
        composeColorPalette().textColorTertiaryInverse.toInt()
    }
    override var textColorPrimaryDisableOnly: Int by SubColorPaletteProp{
        composeColorPalette().textColorPrimaryDisableOnly.toInt()
    }
    override var textColorPrimaryInverseDisableOnly: Int by SubColorPaletteProp{
        composeColorPalette().textColorPrimaryInverseDisableOnly.toInt()
    }
    override var textColorHint: Int by SubColorPaletteProp{
        composeColorPalette().textColorHint.toInt()
    }
    override var textColorHintInverse: Int by SubColorPaletteProp{
        composeColorPalette().textColorHintInverse.toInt()
    }
    override var textColorHighlight: Int by SubColorPaletteProp{
        composeColorPalette().textColorHighlight.toInt()
    }
    override var textColorHighlightInverse: Int by SubColorPaletteProp{
        composeColorPalette().textColorHighlightInverse.toInt()
    }
    override var textColorLink: Int by SubColorPaletteProp{
        composeColorPalette().textColorLink.toInt()
    }
    override var textColorLinkInverse: Int by SubColorPaletteProp{
        composeColorPalette().textColorLinkInverse.toInt()
    }
    override var textColorAlertDialogListItem: Int by SubColorPaletteProp{
        composeColorPalette().textColorAlertDialogListItem.toInt()
    }


}


abstract class ColorPaletteSchemeBase(val palette: ColorPaletteBean): ColorPaletteScheme {
    override var rosewater:Long = palette.rosewater
    override var flamingo: Long = palette.flamingo
    override var pink: Long = palette.pink
    override var mauve: Long = palette.mauve
    override var red: Long = palette.red
    override var maroon: Long = palette.maroon
    override var peach: Long = palette.peach
    override var yellow: Long = palette.yellow
    override var green: Long = palette.green
    override var teal: Long = palette.teal
    override var sky: Long = palette.sky
    override var sapphire: Long = palette.sapphire
    override var blue: Long = palette.blue
    override var lavender: Long = palette.lavender
    override var text: Long = palette.text
    override var subtext0: Long = palette.subtext0
    override var subtext1: Long = palette.subtext1
    override var overlay0: Long = palette.overlay0
    override var overlay1: Long = palette.overlay1
    override var overlay2: Long = palette.overlay2
    override var surface0: Long = palette.surface0
    override var surface1: Long = palette.surface1
    override var surface2: Long = palette.surface2
    override var base: Long = palette.base
    override var mantle: Long = palette.mantle
    override var crust: Long = palette.crust

    override fun fromName(name: String): Long {
        /*palette().colors.forEach {
            if(it.definition.label==name)
                return it
        }*/
        return base
    }

    private val composeColorPaletteScheme by lazy {
        ComposeColorPaletteSchemeSub{this}
    }

    private val androidColorPaletteScheme: ComposeColorPaletteScheme<Int> by lazy{
        AndroidColorPaletteSchemeSub{ toCompose() }
    }

    override fun toAndroid(): ComposeColorPaletteScheme<Int> {
       return androidColorPaletteScheme
    }

    override fun toCompose(): ComposeColorPaletteScheme<Long> {
        return composeColorPaletteScheme
    }
}

@Serializable
data class ColorPaletteStore(
    override var rosewater: Long,
    override var flamingo: Long,
    override var pink: Long,
    override var mauve: Long,
    override var red: Long,
    override var maroon: Long,
    override var peach: Long,
    override var yellow: Long,
    override var green: Long,
    override var teal: Long,
    override var sky: Long,
    override var sapphire: Long,
    override var blue: Long,
    override var lavender: Long,
    override var text: Long,
    override var subtext0: Long,
    override var subtext1: Long,
    override var overlay0: Long,
    override var overlay1: Long,
    override var overlay2: Long,
    override var surface0: Long,
    override var surface1: Long,
    override var surface2: Long,
    override var base: Long,
    override var mantle: Long,
    override var crust: Long
) : ColorPaletteBean {

    fun copyFrom(basePalette: ColorPaletteBean){
        copyTo(basePalette,this)
    }

    companion object {
        fun copyFrom(basePalette: ColorPaletteBean): ColorPaletteStore {
            return ColorPaletteStore(
                basePalette.rosewater,
                basePalette.flamingo,
                basePalette.pink,
                basePalette.mauve,
                basePalette.red,
                basePalette.maroon,
                basePalette.peach,
                basePalette.yellow,
                basePalette.green,
                basePalette.teal,
                basePalette.sky,
                basePalette.sapphire,
                basePalette.blue,
                basePalette.lavender,
                basePalette.text,
                basePalette.subtext0,
                basePalette.subtext1,
                basePalette.overlay0,
                basePalette.overlay1,
                basePalette.overlay2,
                basePalette.surface0,
                basePalette.surface1,
                basePalette.surface2,
                basePalette.base,
                basePalette.mantle,
                basePalette.crust
            )
        }

        fun copyTo(basePalette: ColorPaletteBean, toPalette: ColorPaletteBean) {
            toPalette.rosewater = basePalette.rosewater
            toPalette.flamingo = basePalette.flamingo
            toPalette.pink = basePalette.pink
            toPalette.mauve = basePalette.mauve
            toPalette.red = basePalette.red
            toPalette.maroon = basePalette.maroon
            toPalette.peach = basePalette.peach
            toPalette.yellow = basePalette.yellow
            toPalette.green = basePalette.green
            toPalette.teal = basePalette.teal
            toPalette.sky = basePalette.sky
            toPalette.sapphire = basePalette.sapphire
            toPalette.blue = basePalette.blue
            toPalette.lavender = basePalette.lavender
            toPalette.text = basePalette.text
            toPalette.subtext0 = basePalette.subtext0
            toPalette.subtext1 = basePalette.subtext1
            toPalette.overlay0 = basePalette.overlay0
            toPalette.overlay1 = basePalette.overlay1
            toPalette.overlay2 = basePalette.overlay2
            toPalette.surface0 = basePalette.surface0
            toPalette.surface1 = basePalette.surface1
            toPalette.surface2 = basePalette.surface2
            toPalette.base = basePalette.base
            toPalette.mantle = basePalette.mantle
            toPalette.crust = basePalette.crust
        }

    }
}

open class ColorPaletteSchemeWarp(val basePalette: ColorPaletteScheme,
                                  override var rosewater: Long=basePalette.rosewater,
                                  override var flamingo: Long=basePalette.flamingo,
                                  override var pink: Long=basePalette.pink,
                                  override var mauve: Long=basePalette.mauve,
                                  override var red: Long=basePalette.red,
                                  override var maroon: Long=basePalette.maroon,
                                  override var peach: Long=basePalette.peach,
                                  override var yellow: Long=basePalette.yellow,
                                  override var green: Long=basePalette.green,
                                  override var teal: Long=basePalette.teal,
                                  override var sky: Long=basePalette.sky,
                                  override var sapphire: Long=basePalette.sapphire,
                                  override var blue: Long=basePalette.blue,
                                  override var lavender: Long=basePalette.lavender,
                                  override var text: Long=basePalette.text,
                                  override var subtext0: Long=basePalette.subtext0,
                                  override var subtext1: Long=basePalette.subtext1,
                                  override var overlay0: Long=basePalette.overlay0,
                                  override var overlay1: Long=basePalette.overlay1,
                                  override var overlay2: Long=basePalette.overlay2,
                                  override var surface0: Long=basePalette.surface0,
                                  override var surface1: Long=basePalette.surface1,
                                  override var surface2: Long=basePalette.surface2,
                                  override var base: Long=basePalette.base,
                                  override var mantle: Long=basePalette.mantle,
                                  override var crust: Long=basePalette.crust
): ColorPaletteScheme {
    override fun fromName(name: String): Long {
        return basePalette.fromName(name)
    }

    override fun toAndroid(): ComposeColorPaletteScheme<Int> {
        return basePalette.toAndroid()
    }

    override fun toCompose(): ComposeColorPaletteScheme<Long> {
        return basePalette.toCompose()
    }

    override fun getColorThemeName(): String {
        return basePalette.getColorThemeName()
    }
}


class SubColorPaletteProp<T>(val base:()->T): ReadWriteProperty<Any, T> {
    var cache:T?=null
    override fun getValue(thisRef: Any, property: KProperty<*>): T {
        return  cache?:base()
    }

    override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
        cache = value
    }

}

class SubColorPaletteSaveAbleProp<T>(var cache:T?, val base:()->T): ReadWriteProperty<Any, T> {
    override fun getValue(thisRef: Any, property: KProperty<*>): T {
        return  cache?:base()
    }

    override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
        cache = value
    }
}

class SubColorPaletteReadAbleProp<T>(var cache:T?, val base:()->T):
    ReadOnlyProperty<Any, T> {
    override fun getValue(thisRef: Any, property: KProperty<*>): T {
        return  cache?:base()
    }

}


open class SubColorSchemeImp(basePalette:()-> ColorPaletteScheme):
    SubColorPaletteSchemeImp<ColorPaletteScheme>(basePalette=basePalette)


interface SubColorPaletteScheme: ColorPaletteScheme, StoreControl {

}

@Serializable
class ColorPaletteCache{
     var rosewater: Long?=null
     var flamingo: Long?=null
     var pink: Long?=null
     var mauve: Long?=null
     var red: Long?=null
     var maroon: Long?=null
     var peach: Long?=null
     var yellow: Long?=null
     var green: Long?=null
     var teal: Long?=null
     var sky: Long?=null
     var sapphire: Long?=null
     var blue: Long?=null
     var lavender: Long?=null
     var text: Long?=null
     var subtext0: Long?=null
     var subtext1: Long?=null
     var overlay0: Long?=null
     var overlay1: Long?=null
     var overlay2: Long?=null
     var surface0: Long?=null
     var surface1: Long?=null
     var surface2: Long?=null
     var base: Long?=null
     var mantle: Long?=null
     var crust: Long?=null

    /**
     * Syntax Colours
     */

    var mark1 : Long?=null

    var mark1Text:Long?=null

    var mark2 : Long?=null
    var mark2Text : Long?=null

    var mark3 : Long?=null
    var mark3Text : Long?=null


    /**
     * Window Colours
     */
    var background : Long?=null

    var mainText : Long?=null

    var urls : Long?=null

    var selection : Long?=null

    var selectionText : Long?=null

    var cursor : Long?=null

    var cursorText : Long?=null

    var activeBorder : Long?=null

    var inactiveBorder : Long?=null

    var bellBorder : Long?=null

    /**
     * Regular Colours
     */
    var color0 : Long?=null
    var color1 : Long?=null
    var color2 : Long?=null
    var color3 : Long?=null
    var color4 : Long?=null
    var color5 : Long?=null
    var color6 : Long?=null
    var color7 : Long?=null

    /**
     * Regular Relative Colours
     * 相对色,用于反差大的
     */
    var color0Relative : Long?=null
    var color1Relative : Long?=null
    var color2Relative : Long?=null
    var color3Relative : Long?=null
    var color4Relative : Long?=null
    var color5Relative : Long?=null
    var color6Relative : Long?=null
    var color7Relative : Long?=null

    /**
     * Regular Accompany Colours
     * 相伴色,用于一同显示,看上去不突兀
     */
    var color0Accompany : Long?=null

    var color1Accompany : Long?=null
    var color2Accompany : Long?=null
    var color3Accompany : Long?=null
    var color4Accompany : Long?=null
    var color5Accompany : Long?=null
    var color6Accompany : Long?=null
    var color7Accompany : Long?=null

    /**
     * Regular Accompany other Colours
     * 第二种 相伴色
     */
    var color0Accompany1 : Long?=null
    var color1Accompany1 : Long?=null
    var color2Accompany1 : Long?=null
    var color3Accompany1 : Long?=null
    var color4Accompany1 : Long?=null
    var color5Accompany1 : Long?=null
    var color6Accompany1 : Long?=null
    var color7Accompany1 : Long?=null

    /**
     * Bold Colours
     */
    var boldColor0 : Long?=null
    var boldColor1 : Long?=null
    var boldColor2 : Long?=null
    var boldColor3 : Long?=null
    var boldColor4 : Long?=null
    var boldColor5 : Long?=null
    var boldColor6 : Long?=null
    var boldColor7 : Long?=null

    /**
     * Extended Colours
     */
    var color16 : Long?=null
    var color17 : Long?=null

    fun copyFrom(basePalette: ColorPaletteCache){
        copy(basePalette,this)
    }

    companion object{
        fun copy(basePalette: ColorPaletteCache, toPalette: ColorPaletteCache){
            toPalette.rosewater = basePalette.rosewater
            toPalette.flamingo = basePalette.flamingo
            toPalette.pink = basePalette.pink
            toPalette.mauve = basePalette.mauve
            toPalette.red = basePalette.red
            toPalette.maroon = basePalette.maroon
            toPalette.peach = basePalette.peach
            toPalette.yellow = basePalette.yellow
            toPalette.green = basePalette.green
            toPalette.teal = basePalette.teal
            toPalette.sky = basePalette.sky
            toPalette.sapphire = basePalette.sapphire
            toPalette.blue = basePalette.blue
            toPalette.lavender = basePalette.lavender
            toPalette.text = basePalette.text
            toPalette.subtext0 = basePalette.subtext0
            toPalette.subtext1 = basePalette.subtext1
            toPalette.overlay0 = basePalette.overlay0
            toPalette.overlay1 = basePalette.overlay1
            toPalette.overlay2 = basePalette.overlay2
            toPalette.surface0 = basePalette.surface0
            toPalette.surface1 = basePalette.surface1
            toPalette.surface2 = basePalette.surface2
            toPalette.base = basePalette.base
            toPalette.mantle = basePalette.mantle
            toPalette.crust = basePalette.crust

            toPalette.mark1      =basePalette.mark1

            toPalette.mark1Text  =basePalette.mark1Text

            toPalette.mark2      =basePalette.mark2
            toPalette.mark2Text  =basePalette.mark2Text

            toPalette.mark3      =basePalette.mark3
            toPalette.mark3Text  =basePalette.mark3Text


            /**
             * Window Colours
             */
            toPalette.background =basePalette.background

            toPalette.mainText   =basePalette.mainText

            toPalette.urls       =basePalette.urls

            toPalette.selection  =basePalette.selection

            toPalette.selectionText =basePalette.selectionText

            toPalette.cursor        =basePalette.cursor

            toPalette.cursorText    =basePalette.cursorText

            toPalette.activeBorder  =basePalette.activeBorder

            toPalette.inactiveBorder=basePalette.inactiveBorder

            toPalette.bellBorder    =basePalette.bellBorder

            /**
             * Regular Colours
             */
            toPalette.color0 =basePalette.color0
            toPalette.color1 =basePalette.color1
            toPalette.color2 =basePalette.color2
            toPalette.color3 =basePalette.color3
            toPalette.color4 =basePalette.color4
            toPalette.color5 =basePalette.color5
            toPalette.color6 =basePalette.color6
            toPalette.color7 =basePalette.color7

            /**
             * Regular Relative Colours
             * 相对色,用于反差大的
             */
            toPalette.color0Relative =basePalette.color0Relative
            toPalette.color1Relative =basePalette.color1Relative
            toPalette.color2Relative =basePalette.color2Relative
            toPalette.color3Relative =basePalette.color3Relative
            toPalette.color4Relative =basePalette.color4Relative
            toPalette.color5Relative =basePalette.color5Relative
            toPalette.color6Relative =basePalette.color6Relative
            toPalette.color7Relative =basePalette.color7Relative

            /**
             * Regular Accompany Colours
             * 相伴色,用于一同显示,看上去不突兀
             */
            toPalette.color0Accompany =basePalette.color0Accompany

            toPalette.color1Accompany =basePalette.color1Accompany
            toPalette.color2Accompany =basePalette.color2Accompany
            toPalette.color3Accompany =basePalette.color3Accompany
            toPalette.color4Accompany =basePalette.color4Accompany
            toPalette.color5Accompany =basePalette.color5Accompany
            toPalette.color6Accompany =basePalette.color6Accompany
            toPalette.color7Accompany =basePalette.color7Accompany

            /**
             * Regular Accompany other Colours
             * 第二种 相伴色
             */
            toPalette.color0Accompany1 =basePalette.color0Accompany1
            toPalette.color1Accompany1 =basePalette.color1Accompany1
            toPalette.color2Accompany1 =basePalette.color2Accompany1
            toPalette.color3Accompany1 =basePalette.color3Accompany1
            toPalette.color4Accompany1 =basePalette.color4Accompany1
            toPalette.color5Accompany1 =basePalette.color5Accompany1
            toPalette.color6Accompany1 =basePalette.color6Accompany1
            toPalette.color7Accompany1 =basePalette.color7Accompany1

            /**
             * Bold Colours
             */
            toPalette.boldColor0 =basePalette.boldColor0
            toPalette.boldColor1 =basePalette.boldColor1
            toPalette.boldColor2 =basePalette.boldColor2
            toPalette.boldColor3 =basePalette.boldColor3
            toPalette.boldColor4 =basePalette.boldColor4
            toPalette.boldColor5 =basePalette.boldColor5
            toPalette.boldColor6 =basePalette.boldColor6
            toPalette.boldColor7 =basePalette.boldColor7

            /**
             * Extended Colours
             */
            toPalette.color16=basePalette.color16
            toPalette.color17=basePalette.color17
        }
    }
}

open class SubColorPaletteSchemeImp<P: ColorPaletteScheme>(var storeBean : ColorPaletteCache = ColorPaletteCache(),  val basePalette:()->P):
    SubColorPaletteScheme, StoreControl {

    val STORE_LABEL :String get() =  getColorThemeName()+"_subColorPalette"

    override fun saveToStore(server: StoreServer) {
        server.putPreference(STORE_LABEL,storeBean)
    }

    override fun reStore(server: StoreServer) {
        server.getPreferenceOrNull<ColorPaletteCache>(STORE_LABEL)?.let{
            storeBean = it
        }
    }

    override var rosewater: Long by SubColorPaletteSaveAbleProp(storeBean.rosewater){
        basePalette().rosewater
    }

    override var flamingo: Long by SubColorPaletteSaveAbleProp(storeBean.flamingo){
        basePalette().flamingo
    }
    override var pink: Long by SubColorPaletteSaveAbleProp(storeBean.pink){
        basePalette().pink
    }
    override var mauve: Long by SubColorPaletteSaveAbleProp(storeBean.mauve){
        basePalette().mauve
    }
    override var red: Long by SubColorPaletteSaveAbleProp(storeBean.red){
        basePalette().red
    }
    override var maroon: Long by SubColorPaletteSaveAbleProp(storeBean.maroon){
        basePalette().maroon
    }
    override var peach: Long by SubColorPaletteSaveAbleProp(storeBean.rosewater){
        basePalette().rosewater
    }
    override var yellow: Long by SubColorPaletteSaveAbleProp(storeBean.rosewater){
        basePalette().yellow
    }
    override var green: Long by SubColorPaletteSaveAbleProp(storeBean.green){
        basePalette().green
    }
    override var teal: Long by SubColorPaletteSaveAbleProp(storeBean.teal){
        basePalette().teal
    }
    override var sky: Long by SubColorPaletteSaveAbleProp(storeBean.rosewater){
        basePalette().sky
    }
    override var sapphire: Long by SubColorPaletteSaveAbleProp(storeBean.sapphire){
        basePalette().sapphire
    }
    override var blue: Long by SubColorPaletteSaveAbleProp(storeBean.blue){
        basePalette().blue
    }
    override var lavender: Long by SubColorPaletteSaveAbleProp(storeBean.lavender){
        basePalette().lavender
    }
    override var text: Long by SubColorPaletteSaveAbleProp(storeBean.text){
        basePalette().text
    }
    override var subtext0: Long by SubColorPaletteSaveAbleProp(storeBean.subtext0){
        basePalette().subtext0
    }
    override var subtext1: Long by SubColorPaletteSaveAbleProp(storeBean.subtext1){
        basePalette().subtext1
    }
    override var overlay0: Long by SubColorPaletteSaveAbleProp(storeBean.overlay0){
        basePalette().overlay0
    }
    override var overlay1: Long by SubColorPaletteSaveAbleProp(storeBean.overlay1){
        basePalette().overlay1
    }
    override var overlay2: Long by SubColorPaletteSaveAbleProp(storeBean.overlay2){
        basePalette().overlay2
    }
    override var surface0: Long by SubColorPaletteSaveAbleProp(storeBean.surface0){
        basePalette().surface0
    }
    override var surface1: Long by SubColorPaletteSaveAbleProp(storeBean.surface1){
        basePalette().surface1
    }
    override var surface2: Long by SubColorPaletteSaveAbleProp(storeBean.surface2){
        basePalette().surface2
    }
    override var base: Long by SubColorPaletteSaveAbleProp(storeBean.base){
        basePalette().base
    }
    override var mantle: Long by SubColorPaletteSaveAbleProp(storeBean.mantle){
        basePalette().mantle
    }
    override var crust: Long by SubColorPaletteSaveAbleProp(storeBean.crust){
        basePalette().crust
    }

    override val mark1: Long by SubColorPaletteReadAbleProp(storeBean.mark1){
        basePalette().mark1
    }
    override val mark1Text: Long by SubColorPaletteReadAbleProp(storeBean.mark1Text){
        basePalette().mark1Text
    }
    override val mark2: Long by SubColorPaletteReadAbleProp(storeBean.mark2){
        basePalette().mark2
    }
    override val mark2Text: Long by SubColorPaletteReadAbleProp(storeBean.mark2Text){
        basePalette().mark2Text
    }
    override val mark3: Long by SubColorPaletteReadAbleProp(storeBean.mark3){
        basePalette().mark3
    }
    override val mark3Text: Long by SubColorPaletteReadAbleProp(storeBean.mark3Text){
        basePalette().mark3Text
    }
    override val background: Long by SubColorPaletteReadAbleProp(storeBean.background){
        basePalette().background
    }
    override val mainText: Long by SubColorPaletteReadAbleProp(storeBean.mainText){
        basePalette().mainText
    }
    override val urls: Long by SubColorPaletteReadAbleProp(storeBean.urls){
        basePalette().urls
    }
    override val selection: Long by SubColorPaletteReadAbleProp(storeBean.selection){
        basePalette().selection
    }
    override val selectionText: Long by SubColorPaletteReadAbleProp(storeBean.selectionText){
        basePalette().selectionText
    }
    override val cursor: Long by SubColorPaletteReadAbleProp(storeBean.cursor){
        basePalette().cursor
    }
    override val cursorText: Long by SubColorPaletteReadAbleProp(storeBean.cursorText){
        basePalette().cursorText
    }
    override val activeBorder: Long by SubColorPaletteReadAbleProp(storeBean.activeBorder){
        basePalette().activeBorder
    }
    override val inactiveBorder: Long by SubColorPaletteReadAbleProp(storeBean.inactiveBorder){
        basePalette().inactiveBorder
    }
    override val bellBorder: Long by SubColorPaletteReadAbleProp(storeBean.bellBorder){
        basePalette().bellBorder
    }
    override val color0: Long by SubColorPaletteReadAbleProp(storeBean.color0){
        basePalette().color0
    }
    override val color1: Long by SubColorPaletteReadAbleProp(storeBean.color1){
        basePalette().color1
    }
    override val color2: Long by SubColorPaletteReadAbleProp(storeBean.color2){
        basePalette().color2
    }
    override val color3: Long by SubColorPaletteReadAbleProp(storeBean.color3){
        basePalette().color3
    }
    override val color4: Long by SubColorPaletteReadAbleProp(storeBean.color4){
        basePalette().color4
    }
    override val color5: Long by SubColorPaletteReadAbleProp(storeBean.color5){
        basePalette().color5
    }
    override val color6: Long by SubColorPaletteReadAbleProp(storeBean.color6){
        basePalette().color6
    }
    override val color7: Long by SubColorPaletteReadAbleProp(storeBean.color7){
        basePalette().color7
    }
    override val color0Relative: Long by SubColorPaletteReadAbleProp(storeBean.color0Relative){
        basePalette().color0Relative
    }
    override val color1Relative: Long by SubColorPaletteReadAbleProp(storeBean.color1Relative){
        basePalette().color1Relative
    }
    override val color2Relative: Long by SubColorPaletteReadAbleProp(storeBean.color2Relative){
        basePalette().color2Relative
    }
    override val color3Relative: Long by SubColorPaletteReadAbleProp(storeBean.color3Relative){
        basePalette().color3Relative
    }
    override val color4Relative: Long by SubColorPaletteReadAbleProp(storeBean.color4Relative){
        basePalette().color4Relative
    }
    override val color5Relative: Long by SubColorPaletteReadAbleProp(storeBean.color5Relative){
        basePalette().color5Relative
    }
    override val color6Relative: Long by SubColorPaletteReadAbleProp(storeBean.color6Relative){
        basePalette().color6Relative
    }
    override val color7Relative: Long by SubColorPaletteReadAbleProp(storeBean.color7Relative){
        basePalette().color7Relative
    }
    override val color0Accompany: Long by SubColorPaletteReadAbleProp(storeBean.color0Accompany){
        basePalette().color0Accompany
    }
    override val color1Accompany: Long by SubColorPaletteReadAbleProp(storeBean.color1Accompany){
        basePalette().color1Accompany
    }
    override val color2Accompany: Long by SubColorPaletteReadAbleProp(storeBean.color2Accompany){
        basePalette().color2Accompany
    }
    override val color3Accompany: Long by SubColorPaletteReadAbleProp(storeBean.color3Accompany){
        basePalette().color3Accompany
    }
    override val color4Accompany: Long by SubColorPaletteReadAbleProp(storeBean.color4Accompany){
        basePalette().color4Accompany
    }
    override val color5Accompany: Long by SubColorPaletteReadAbleProp(storeBean.color5Accompany){
        basePalette().color5Accompany
    }
    override val color6Accompany: Long by SubColorPaletteReadAbleProp(storeBean.color6Accompany){
        basePalette().color6Accompany
    }
    override val color7Accompany: Long by SubColorPaletteReadAbleProp(storeBean.color7Accompany){
        basePalette().color7Accompany
    }
    override val color0Accompany1: Long by SubColorPaletteReadAbleProp(storeBean.color0Accompany1){
        basePalette().color0Accompany1
    }
    override val color1Accompany1: Long by SubColorPaletteReadAbleProp(storeBean.color1Accompany1){
        basePalette().color1Accompany1
    }
    override val color2Accompany1: Long by SubColorPaletteReadAbleProp(storeBean.color2Accompany1){
        basePalette().color2Accompany1
    }
    override val color3Accompany1: Long by SubColorPaletteReadAbleProp(storeBean.color3Accompany1){
        basePalette().color3Accompany1
    }
    override val color4Accompany1: Long by SubColorPaletteReadAbleProp(storeBean.color4Accompany1){
        basePalette().color4Accompany1
    }
    override val color5Accompany1: Long by SubColorPaletteReadAbleProp(storeBean.color5Accompany1){
        basePalette().color5Accompany1
    }
    override val color6Accompany1: Long by SubColorPaletteReadAbleProp(storeBean.color6Accompany1){
        basePalette().color6Accompany1
    }
    override val color7Accompany1: Long by SubColorPaletteReadAbleProp(storeBean.color7Accompany1){
        basePalette().color7Accompany1
    }
    override val boldColor0: Long by SubColorPaletteReadAbleProp(storeBean.boldColor0){
        basePalette().boldColor0
    }
    override val boldColor1: Long by SubColorPaletteReadAbleProp(storeBean.boldColor1){
        basePalette().boldColor1
    }
    override val boldColor2: Long by SubColorPaletteReadAbleProp(storeBean.boldColor2){
        basePalette().boldColor2
    }
    override val boldColor3: Long by SubColorPaletteReadAbleProp(storeBean.boldColor3){
        basePalette().boldColor3
    }
    override val boldColor4: Long by SubColorPaletteReadAbleProp(storeBean.boldColor4){
        basePalette().boldColor4
    }
    override val boldColor5: Long by SubColorPaletteReadAbleProp(storeBean.boldColor5){
        basePalette().boldColor5
    }
    override val boldColor6: Long by SubColorPaletteReadAbleProp(storeBean.boldColor6){
        basePalette().boldColor6
    }
    override val boldColor7: Long by SubColorPaletteReadAbleProp(storeBean.boldColor7){
        basePalette().boldColor7
    }
    override val color16: Long by SubColorPaletteReadAbleProp(storeBean.color16){
        basePalette().color16
    }
    override val color17: Long by SubColorPaletteReadAbleProp(storeBean.color17){
        basePalette().color17
    }

    override fun fromName(name: String): Long {
        return basePalette().fromName(name)
    }

    private val composeColorPaletteScheme by lazy {
        ComposeColorPaletteSchemeSub{this}
    }

    private val androidColorPaletteScheme: ComposeColorPaletteScheme<Int> by lazy{ AndroidColorPaletteSchemeSub{ toCompose() } }

    override fun toAndroid(): ComposeColorPaletteScheme<Int> {
        return androidColorPaletteScheme
    }

    override fun toCompose(): ComposeColorPaletteScheme<Long> {
        return composeColorPaletteScheme
    }

    override fun getColorThemeName(): String {
        return basePalette().getColorThemeName()
    }
}